# -*- coding: utf-8 -*-
#
# author: Tobiasz Siemiński
# creation date: 24.04.2011


#TODO:
# V 1.01
# -gdy w pliku config jest sciezka do pliku a ten plik nie istnieje to program sie nie odpala #DONE
# -gdy w dacie podamy jakis string to program sie wysypuje #DONE 
# V 1.02
# -dodać polskie znaki, http://pl.python.org/forum/index.php?topic=784.0 #DONE
# -dodać do info na forum statystyki wylosowanych druzyn #DONE
# V 1.1
# -poprawić alogrytm wybierania składów #DONE
# V 1.11
# -poprawić błąd polskich znaków na windowsie #DONE
# V 1.12
# -dodać przycisk "<<< usuń wszystkich" #DONE
# -dodać panel wyboru daty #DONE

import sys
import ioFunctions as ioF #IO Functions
import player as PL #Player Class
import QTeamGenerationResultWidget as generateWidget
import QMyCalendarWidget as calendarWidget
import datetime
from PyQt4 import QtGui, QtCore, Qt

#===== STAŁE
WIDTH = 900 #szerokość okna
HEIGHT = 400 #wysokość okna
DIRECTORY = '.'
VERSION = "1.12 beta"
#=====

class Gui(QtGui.QWidget):
	def __init__(self, parent=None):
		QtGui.QWidget.__init__(self, parent)

		#Ustawienia poczatkowe
		self.setGeometry(0, 0, WIDTH, HEIGHT) #rozmiary
		self.setWindowTitle('Skuadak'+" "+VERSION) #tytuł
		self.setWindowIcon(QtGui.QIcon('images/football_icon.png')) #ikonka
		self.center() #wyśrodkuj
		self.initUI() #zbuduj UI

	#wyśrodkuj okno programu
	def center(self):
		""" Funkcja służąca do wyśrodkowania okienka aplikacji na ekranie """
		screen = QtGui.QDesktopWidget().screenGeometry()
		size = self.geometry()
		self.move((screen.width()-size.width())/2, (screen.height()-size.height())/2)

	#zainicjuj i dodaj wszystkie elementy gui
	def initUI(self):
		""" Funkcja służąca do zainicjowania całego okienka GUI oraz rozmieszczenia elementów w oknie """
		#==================== EDYCJA ZAWODNIKA

		# labele + lineEdity do umiejetnosci zawodnika
		editPlayerLabel = QtGui.QLabel('EDYCJA ZAWODNIKA')
		editPlayerLabelBeforeEdit = QtGui.QLabel('Wybierz zawodnika w celu edycji.')
		nickLabel = QtGui.QLabel('Nick:')
		self.nickEdit = QtGui.QLineEdit()
		self.nickEdit.setReadOnly(True)

		skill1Label = QtGui.QLabel('Opanowanie:')
		self.skill1Edit = QtGui.QComboBox()
		self.skill1Edit.addItems(QtCore.QStringList(ioF.getScale()))
		

		skill2Label = QtGui.QLabel(u'Sprawność fizyczna:')
		self.skill2Edit = QtGui.QComboBox()
		self.skill2Edit.addItems(QtCore.QStringList(ioF.getScale()))
		skill3Label = QtGui.QLabel('Technika:')
		self.skill3Edit = QtGui.QComboBox()
		self.skill3Edit.addItems(QtCore.QStringList(ioF.getScale()))
		skill4Label = QtGui.QLabel(u'Zaangażowanie:')
		self.skill4Edit = QtGui.QComboBox()
		self.skill4Edit.addItems(QtCore.QStringList(ioF.getScale()))

		# combo box zawierajacy pozycje na ktorej zawodnik gra
		positionLabel = QtGui.QLabel('Pozycja:')
		self.positionEdit = QtGui.QComboBox()
		self.positionEdit.addItems(QtCore.QStringList(ioF.getPositions()))

		# suma umiejetnosci
		overallLabel = QtGui.QLabel('Suma:')
		self.overallSumLabel = QtGui.QLabel('')

		# zapisanie zawodnika do slownika
		savePlayerButton = QtGui.QPushButton('Zapisz')
		self.connect(savePlayerButton, Qt.SIGNAL('clicked()'), self.savePlayerChanges)

		# wczytywanie zawodnikow z pliku
		loadPlayersFromFileButton = QtGui.QPushButton(u'Wczytaj zawodników z pliku')
		self.connect(loadPlayersFromFileButton, Qt.SIGNAL('clicked()'), self.showQFileDialog)

		# zapisywanie zawodnikow do pliku
		saveAllButton = QtGui.QPushButton('Zapisz wszystkie zmiany do pliku')
		self.connect(saveAllButton, Qt.SIGNAL('clicked()'), self.saveAllChanges)

		#==================== MENU ZAWODNIKOW
		playersLabel = QtGui.QLabel(u'LISTA ZAWODNIKÓW')

		# == lista zawodników
		self.playersList = QtGui.QListWidget() #widget

		# wczytywanie z configa
		self.checkConfigFile()
		self.playersLabelsList = self.players.keys() #utworz liste labeli ze slownika
		self.playersLabelsList.sort() #posortuj ja
		self.playersList.addItems(QtCore.QStringList(self.playersLabelsList)) #dodaj liste do widgetu
		self.playersList.itemClicked.connect(self.updatePlayer) #podepnij funkcje pod akcje
		
		# dodaj wszystkich zawodnikow bioracych udzial w wydarzeniu
		addAllPlayersToEventButton = QtGui.QPushButton('Dodaj wszystkich >>>')
		self.connect(addAllPlayersToEventButton, Qt.SIGNAL('clicked()'), self.addAllPlayersToEvent)

		# dodaj zawodnika do listy zawodnikow bioracych udzial w wydarzeniu
		addPlayerToEventButton = QtGui.QPushButton('Dodaj >>>')
		self.connect(addPlayerToEventButton, Qt.SIGNAL('clicked()'), self.addPlayerToEventList)

		# dodaj nowego zawodnika do bazy
		addPlayerButton = QtGui.QPushButton('Dodaj')
		self.connect(addPlayerButton, Qt.SIGNAL('clicked()'), self.showNewPlayerDialog)

		# usun zawodnika z bazy
		deletePlayerButton = QtGui.QPushButton(u'Usuń')
		self.connect(deletePlayerButton, Qt.SIGNAL('clicked()'), self.removePlayer)

		#==================== WYDARZENIE
		eventLabel = QtGui.QLabel('WYDARZENIE')
		placeLabel = QtGui.QLabel('Miejsce:')
		self.placeEdit = QtGui.QLineEdit()

		# data
		dateLabel = QtGui.QLabel('Data:')
		self.dateEdit = QtGui.QLineEdit()

		# wstaw dzisiejsza date
		insertTodayDateButton = QtGui.QPushButton(u'Wstaw datę')
		self.connect(insertTodayDateButton, Qt.SIGNAL('clicked()'), self.insertTodayDate)

		# godzina
		hourLabel = QtGui.QLabel('Godzina:')
		self.hourEdit = QtGui.QLineEdit()

		# wstaw obecna godzine
		insertNowTimeButton = QtGui.QPushButton('Wstaw teraz')
		self.connect(insertNowTimeButton, Qt.SIGNAL('clicked()'), self.insertNowTime)

		# lista zawodnikow bioracych udzial w wydarzeniu
		eventPlayersLabel = QtGui.QLabel(u'Zawodnicy biorący udział')
		self.eventPlayersList = QtGui.QListWidget() # widget
		self.eventPlayersList.itemClicked.connect(self.updatePlayer) # podepnij akcje odswiezenia info o graczu
		self.eventPlayers = {} # zainicjuj pusty slownik
		self.eventPlayersLabelsList = [] # liste labelow zawodnikow

		# usun zawodnika z listy zawodnikow bioracych udzial w wydarzeniu
		deletePlayerFromEventButton = QtGui.QPushButton(u'<<< Usuń')
		self.connect(deletePlayerFromEventButton, Qt.SIGNAL('clicked()'), self.removePlayerFromEventList)

		# usun wszystkich zawodnikow z listy bioracych udzial w wydarzeniu
		deleteAllPlayersFromEventButton = QtGui.QPushButton(u'<<< Usuń wszystkich')
		self.connect(deleteAllPlayersFromEventButton, Qt.SIGNAL('clicked()'), self.removeAllPlayersFromEventList)

		# generuj sklady!
		generateTeamsButton = QtGui.QPushButton('Generuj sklady!')
		self.connect(generateTeamsButton, Qt.SIGNAL('clicked()'), self.showGenerationWidget)

		# o autorze
		aboutAuthorButton = QtGui.QPushButton('O autorze')
		self.connect(aboutAuthorButton, Qt.SIGNAL('clicked()'), self.aboutAuthor)

		#=================== GRID LAYOUT
		grid = QtGui.QGridLayout()
		grid.setSpacing(10)

		#== edycja zawodnika
		grid.addWidget(editPlayerLabel, 0, 0)
		grid.addWidget(nickLabel, 1, 0)
		grid.addWidget(self.nickEdit, 1, 1, 1, 2)
		grid.addWidget(positionLabel, 2, 0)
		grid.addWidget(self.positionEdit, 2, 1, 1, 2)
		grid.addWidget(skill1Label, 3, 0)
		grid.addWidget(self.skill1Edit, 3, 1, 1, 2)
		grid.addWidget(skill2Label, 4, 0)
		grid.addWidget(self.skill2Edit, 4, 1, 1, 2)
		grid.addWidget(skill3Label, 5, 0)
		grid.addWidget(self.skill3Edit, 5, 1, 1, 2)
		grid.addWidget(skill4Label, 6, 0)
		grid.addWidget(self.skill4Edit, 6, 1, 1, 2)
		grid.addWidget(overallLabel, 7, 0)
		grid.addWidget(self.overallSumLabel, 7, 1, 1, 2)
		grid.addWidget(savePlayerButton, 8, 0, 1, 1)
		grid.addWidget(loadPlayersFromFileButton, 8, 1, 1, 2)
		grid.addWidget(saveAllButton, 9, 0, 1, 3)

		#== menu zawodników
		grid.addWidget(playersLabel, 0, 3)
		grid.addWidget(self.playersList, 1, 3, 7, 3)
		grid.addWidget(addAllPlayersToEventButton, 8, 3, 1, 2)
		grid.addWidget(addPlayerToEventButton, 8, 5, 1, 1)
		grid.addWidget(addPlayerButton, 9, 3, 1, 2)
		grid.addWidget(deletePlayerButton, 9, 5, 1, 1)

		#== wydarzenie
		grid.addWidget(eventLabel, 0, 6)
		grid.addWidget(placeLabel, 1, 6)
		grid.addWidget(self.placeEdit, 1, 7, 1, 3)
		grid.addWidget(dateLabel, 2, 6)
		grid.addWidget(self.dateEdit, 2, 7, 1, 2)
		grid.addWidget(insertTodayDateButton, 2, 9)
		grid.addWidget(hourLabel, 3, 6)
		grid.addWidget(self.hourEdit, 3, 7, 1, 2)
		grid.addWidget(insertNowTimeButton, 3, 9)
		grid.addWidget(eventPlayersLabel, 4, 6, 1, 2)
		grid.addWidget(self.eventPlayersList, 5, 6, 3, 4)
		grid.addWidget(deletePlayerFromEventButton, 8, 6)
		grid.addWidget(deleteAllPlayersFromEventButton, 8, 7, 1, 3)
		grid.addWidget(generateTeamsButton, 9, 7, 1, 3)	
		grid.addWidget(aboutAuthorButton, 9, 6, 1, 1)
		self.setLayout(grid)
	
	#Okienko z informacjami o autorze	
	def aboutAuthor(self):
		author = QtGui.QMessageBox.information(self, QtCore.QString("O autorze"), u"autor: Tobiasz Siemiński\nemail: sortris [at] gmail [dot] com")		

	#sprawdz czy plik konfiguracyjny istnieje, jesli tak, to wczytaj z niego sciezke do pliku z graczami i odczytaj liste
	def checkConfigFile(self):
		try:
			file = open("config.cfg", "r")
		except:
			self.players = {}
			return
		text = file.read()
		file.close()
		self.players = ioF.loadPlayersFromFile(self, text) #wczytanie listy z pliku podczas inicjalizacji programu 
		
		

	#pokaz okno wyboru pliku do wczytania zawodnikow 
	def showQFileDialog(self):
		""" Funkcja pokazująca okienko do wyboru pliku do otwarcia, z którego zostaną wczytani zawodnicy. """
		filename = QtGui.QFileDialog.getOpenFileName(self, 'Otworz plik', DIRECTORY)
		if filename == "":
			return
		#zapisz do configa ostatnio otwierany plik z graczami
		file = open("config.cfg", "w")
		file.write(filename)
		file.close()

		self.players = ioF.loadPlayersFromFile(self, filename)
		self.refreshPlayersList()

	# odswiez info o zawodniku, ktory zostal wybrany na liscie
	def updatePlayer(self):
		""" Funkcja odswieza labele i combo boxy, informacje o zawodniku, który został wybrany na jednej z list.
		Jeśli główna lista zawodników jest pusta, po wybraniu zawodnika na liście zawodników wydarzenia, 
		również zostanie pokazana o nim informacja. """ 

		pl1 = self.playersList.currentItem()
		pl2 = self.eventPlayersList.currentItem()
		if pl1 == None and pl2 == None:
			return
		elif pl1 != None:
			selectedPlayer = unicode(str(pl1.text()))
			player = self.players[selectedPlayer]
		elif pl1 == None and pl2 != None:
			selectedPlayer = unicode(str(pl2.text()))
			player = self.eventPlayers[selectedPlayer]	

		self.nickEdit.setText(unicode(player.nick))
		scale = ioF.getScale()
		self.skill1Edit.setCurrentIndex(player.composure-1)
		self.skill2Edit.setCurrentIndex(player.physicalFitness-1)
		self.skill3Edit.setCurrentIndex(player.technique-1)
		self.skill4Edit.setCurrentIndex(player.engagement-1)

		#umozliw edycje, wczesniej moglo byc readonly
		self.nickEdit.setReadOnly(False)

		pos = ioF.getPositions()
		self.positionEdit.setCurrentIndex(pos.index(player.position))
		self.overallSumLabel.setText(str(int(player.composure)+int(player.physicalFitness)+int(player.technique)+int(player.engagement)))

	# pokaz prompta o imie nowego zawodnika
	def showNewPlayerDialog(self):
		""" Funkcja pokazująca okienko wpisywania imienia nowego zawodnika """
		newPlayerName, ok = QtGui.QInputDialog.getText(self, 'Nowy zawodnik', 'Podaj nick nowego zawodnika:')
		if ok:
			self.players[unicode(str(newPlayerName))] = PL.Player(unicode(str(newPlayerName)))
			self.refreshPlayersList()

	# zapisz zmiany w zawodniku
	def savePlayerChanges(self):
		""" Funkcja służąca do pobrania informacji z pola edycji i zapisaniu danych zawodnika w słowniku zawodników. """
		if self.playersList.currentItem() == None:
			return
		else:
			selectedPlayer = unicode(str(self.playersList.currentItem().text()))
			player = self.players[selectedPlayer]
			player.nick = unicode(str(self.nickEdit.text()))

			scale = ioF.getScale()			
			player.composure = int(self.skill1Edit.currentIndex()+1)
	 		player.physicalFitness = int(self.skill2Edit.currentIndex()+1)
			player.technique = int(self.skill3Edit.currentIndex()+1)
			player.engagement = int(self.skill4Edit.currentIndex()+1)

			pos = ioF.getPositions()
			player.position = pos[self.positionEdit.currentIndex()]
			del self.players[selectedPlayer] # usun starego
			#TODO Byc moze mozna to bylo inaczej rozwiazac, nie chce mi sie sprawdzac
			self.players[unicode(player.nick)] = player # dodaj nowego 

			self.refreshPlayersList()
			self.overallSumLabel.setText(str(int(player.composure)+int(player.physicalFitness)+int(player.technique)+int(player.engagement)))

	# zapisz wszystkie zmiany do pliku
	def saveAllChanges(self):
		""" Funkcja służąca do pobrania pliku, do którego mają zostać zapisani zawodnicy i zapisania ich do tego pliku. """
		filename = QtGui.QFileDialog.getSaveFileName(self, 'Zapisz plik', DIRECTORY)
		if filename == "":
			return

		#zapisz do configa ostatnio otwierany plik z graczami
		file = open("config.cfg", "w")
		file.write(filename)
		file.close()

		ioF.savePlayersToFile(dict(self.eventPlayers.items()+self.players.items()), filename)

	# usun zawodnika
	def removePlayer(self):
		""" Funkcja usuwa zawodnika ze słownika """
		if self.playersList.currentItem() == None:
			return
		else:
			selectedPlayer = unicode(str(self.playersList.currentItem().text()))
			del self.players[selectedPlayer]
			self.refreshPlayersList()

	# dodaje nowego zawodnika do slownika i listy
	def addPlayerToEventList(self):
		""" Funkcja dodaje nowego zawodnika do listy-widgetu i słownika """
		if self.playersList.currentItem() == None:
			return
		else:
			selectedPlayer = unicode(str(self.playersList.currentItem().text()))
			player = self.players[selectedPlayer]
			del self.players[selectedPlayer]
			self.eventPlayers[selectedPlayer] = player
			self.refreshPlayersList()
			self.refreshEventPlayersList()

	# usuwa zawodnika z listy osob bioracych udzial w danym wydarzeniu
	def removePlayerFromEventList(self):
		""" Usuwa zawodnika z listy osób biorących udział w danym wydarzeniu. """
		if self.eventPlayersList.currentItem() == None:
			return
		else:
			selectedPlayer = unicode(str(self.eventPlayersList.currentItem().text()))
			player = self.eventPlayers[selectedPlayer]
			del self.eventPlayers[selectedPlayer]
			self.players[selectedPlayer] = player
			self.refreshPlayersList()
			self.refreshEventPlayersList()

	# usuwa wszystkich zawodnikow z listy bioracych udzial w wydarzeniu
	def removeAllPlayersFromEventList(self):
		""" Usuwa wszystkich zawodników z listy biorących udział w wydarzeniu """
		self.players = dict(self.eventPlayers.items()+self.players.items())
		self.eventPlayers = {}
		self.refreshPlayersList()
		self.refreshEventPlayersList()

	# dodaje wszystkich zawodnikow do listy bioracych udzial w wydarzeniu
	def addAllPlayersToEvent(self):
		""" Dodaje wszystkich zawodników do listy biorących udział w wydarzeniu """
		self.eventPlayers = dict(self.eventPlayers.items()+self.players.items())
		self.players = {}
		self.refreshPlayersList()
		self.refreshEventPlayersList()

	# wstawia dzisiejsza date do pola edycji
	def insertTodayDate(self):
		self.calendarWidget = calendarWidget.QMyCalendarWidget(self.dateEdit)
		self.calendarWidget.show()
		#self.dateEdit.setText(str(datetime.date.today()))

	# wstawia obecna godzine z minutami w pole edycji
	def insertNowTime(self):
		self.hourEdit.setText(str(datetime.datetime.now().hour)+":"+str(datetime.datetime.now().minute))

	# odswieza liste-baze-widget zawodnikow
	def refreshPlayersList(self):
		self.playersLabelsList = self.players.keys()
		self.playersLabelsList.sort()
		self.playersList.clear()
		self.playersList.addItems(QtCore.QStringList(self.playersLabelsList))

	# odswieza liste-widget zawodnikow bioracych udzial w danym wydarzeniu
	def refreshEventPlayersList(self):
		self.eventPlayersLabelsList = self.eventPlayers.keys()
		self.eventPlayersLabelsList.sort()
		self.eventPlayersList.clear()
		self.eventPlayersList.addItems(QtCore.QStringList(self.eventPlayersLabelsList))

	#Okno wynikowe wygenerowanych skladow!
	def showGenerationWidget(self):
		# czy miejsce zostalo podane
		place = self.placeEdit.text()
		if place == "":		
			reply = QtGui.QMessageBox.warning(self, QtCore.QString(u"Błąd!"), "Pole 'Miejsce zdarzenia' jest puste!")		
			return
		#czy data zostala podana
		date = self.dateEdit.text()
		if date == "":		
			reply = QtGui.QMessageBox.warning(self, QtCore.QString(u"Błąd!"), "Pole 'Data zdarzenia' jest puste!")		
			return
		# sprawdz czy data ma dobry format
		tab = date.split("-")
		if len(tab) > 2:
			try:
				self.mydate = datetime.date(int(tab[0]), int(tab[1]), int(tab[2]))
			except ValueError:
				reply = QtGui.QMessageBox.warning(self, QtCore.QString(u"Błąd!"), u"Podany został błędny format daty. Oczekiwany format: yyyy-mm-dd.")
				return 
		#czy czas zostal podany
		time = self.hourEdit.text()
		if time == "":		
			reply = QtGui.QMessageBox.warning(self, QtCore.QString(u"Błąd!"), "Pole 'Godzina zdarzenia' jest puste!")		
			return

		self.generateWidget = generateWidget.QTeamGenerationResultWidget(place, date, time, self.eventPlayers.copy())
		self.generateWidget.show()

#START	
app = QtGui.QApplication(sys.argv) #appka
gui = Gui() # guj
gui.show() # pokaz GUI
sys.exit(app.exec_()) # zepnij zakonczenie pracy programu z krzyzykiem








